package com.cn.xiaonuo.core.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 日期工具类
 *
 * @author E20151109
 *
 */
public final class DateUtils {
	private DateUtils() {
	}

	public static final String PATTERN_HH_mm_ss = "HH:mm:ss";
	public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public static final String DATE_TIME_FORMAT_BACK = "yyyy/MM/dd HH:mm:ss";

	public static final String DATE_TIME_FORMAT_BACK_YYYY_MM_DD_HH_MM = "yyyy/MM/dd HH:mm";

	public static final String DATE_PATTERN_YYYY_MM_DD = "yyyy-MM-dd";

	public static final String DATE_PATTERN_YYYY_MM = "yyyy-MM";
	public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";

	public static final String DATE_PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static final String DATE_PATTERN_YYYYMMDD_HHMMSS = "yyyyMMdd-HHmmss";
	public static final String DATE_PATTERN_YYYYMMDDHHMM = "yyyyMMddHHmm";

	public static final String DATE_PATTERN_YYYYMMDDHHMMSS_SSS = "yyyyMMddHHmmSSS";

	public static final String DATE_PARENT_YYMMDDHHMMSS_SSS = "yyMMddHHmmSSS";
	public static final String DATE_PARENT_YYMMDDHHMM = "yyMMddHHmm";
	public static final String DATE_PATTERN_YYYYMMDDHH = "yyyyMMddHH";

	public static final String DATE_PATTERN_YYMMDDHH = "yyMMddHH";
	public static final String DATE_PATTERN_YYYYMMDD = "yyyyMMdd";

	public static final String DATE_YYMMDDHHSSSSS = "yyMMddHH";


	public static final String TIME_PATTERN_HHMMSS = "HHmmSS";

	public static final String MONGTH_PATTERN_YYYYMM = "yyyyMM";

	public static final String DATE_PATTERN_YYMMDDHHMMSS = "yyMMddHHmmss";

	public static final String DATE_PATTERN_YYYY = "yyyy";
	public static final String DATE_PATTERN_MMdd = "MMdd";

	public static final String DATE_PATTERN_CHINESE_YYYY_MM_DD = "yyyy年M月d日";


	public static final String DATE_PATTERN_CHINESE_MM_DD = "M月d日";

	public static final String DATE_PATTERN_CHINESE_YYYY_MM_DD_HH_MM = "yyyy年M月d日 HH:mm";

	public static final String DATE_TIME_FORMAT_SLASH_MM_DD_HH_MM= "MM/dd HH:mm";
	/**
	 * 获取当前时间:默认格式yyyy-MM-dd HH:mm:ss
	 *
	 * @return
	 */
	public static String getCurrentDateStr() {
		LocalDateTime currentDate = LocalDateTime.now();
		DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT);
		return currentDate.format(dateFormat);
	}

	/**
	 * 过去多少时间
	 * @param time
	 * @return
	 */
	public static String getlastTimes(Date time){



		return getChineseTime(System.currentTimeMillis()-time.getTime());
	}

	public static String getChineseTime(long ms){
		Integer ss = 1000;
		Integer mi = ss * 60;
		Integer hh = mi * 60;
		Integer dd = hh * 24;

		Long day = ms / dd;
		Long hour = (ms - day * dd) / hh;
		Long minute = (ms - day * dd - hour * hh) / mi;
		Long second = (ms - day * dd - hour * hh - minute * mi) / ss;
		Long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

		StringBuffer sb = new StringBuffer();
		if(day > 0) {
			sb.append(day+"天");
		}
		if(hour > 0) {
			sb.append(hour+"小时");
		}
		if(minute > 0) {
			sb.append(minute+"分");
		}
		if(second > 0) {
			sb.append(second+"秒");
		}
		/*if(milliSecond > 0) {
			sb.append(milliSecond+"毫秒");
		}*/
		sb.append("前");
		return sb.toString();

	}
	/**
	 * 获取当前时间
	 *
	 * @param format
	 * @return
	 */
	public static final String getCurrentDateStr(String format) {
		if (StringUtils.isEmpty(format)) {
			return getCurrentDateStr();
		}
		LocalDateTime currentDate = LocalDateTime.now();
		DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(format);
		return currentDate.format(dateFormat);
	}

	/**
	 * 格式化时间
	 *
	 * @param source
	 * @return
	 */
	public static final String formatDate(Date source) {
		return formatDate(source, null);
	}

	/**
	 * 格式化时间
	 *
	 * @param source
	 * @param format
	 * @return
	 */
	public static final String formatDate(Date source, String format) {
		if (source == null) {
			return "";
		}
		DateFormat dateFormat = null;
		if (StringUtils.isEmpty(format)) {
			dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
		} else {
			dateFormat = new SimpleDateFormat(format);
		}
		return dateFormat.format(source);
	}

	/**
	 * 解析日期字符串.默认个格式
	 *
	 * @param source
	 * @return
	 */
	public static final Date parseDateStr(String source) {
		if (StringUtils.isEmpty(source)) {
			return null;
		}
		DateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
		try {
			return dateFormat.parse(source);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 解析时间字符串：默认是按照yyyy-MM-dd HH:mm:ss解析
	 *
	 * @param source
	 * @param format
	 * @return
	 */
	public static final Date parseDateStr(String source, String format) {
		if (StringUtils.isEmpty(source)) {
			return null;
		}
		DateFormat dateFormat = null;
		if (StringUtils.isEmpty(format)) {
			dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT);
		} else {
			dateFormat = new SimpleDateFormat(format);
		}
		try {
			return dateFormat.parse(source);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 查询今天的前/后几天的整日日期
	 * <p/>
	 * 比如2015-12-18日的前一天--2015-12-17
	 * <p/>
	 * 比如2015-12-18日的后一天--2015-12-19
	 *
	 * @param day
	 * @return
	 */
	public static String getDayBeforeOrAfter(Integer day) {
		// 今天整天日期
		Date currDt = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN_YYYY_MM_DD);
		String currDtStr = sdf.format(currDt.getTime());
		Date currDay = null;
		try {
			currDay = sdf.parse(currDtStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date(currDay.getTime()));
		calendar.add(Calendar.DATE, day);
		Date target = calendar.getTime();
		return sdf.format(target);
	}

	/**
	 * 查询某天的前/后几天的整日日期
	 * <p/>
	 * 比如2015-12-18日的前一天--2015-12-17
	 * <p/>
	 * 比如2015-12-18日的后一天--2015-12-19
	 *
	 * @param day
	 * @return
	 */
	public static String getDayBeforeOrAfter(Date sourceDt, Integer day) {
		// 今天整天日期
		if (sourceDt == null) {
			sourceDt = new Date();
		}
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_PATTERN_YYYY_MM_DD);
		String sourceDtStr = sdf.format(sourceDt.getTime());
		Date sourceDay = null;
		try {
			sourceDay = sdf.parse(sourceDtStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date(sourceDay.getTime()));
		calendar.add(Calendar.DATE, day);
		Date target = calendar.getTime();
		return sdf.format(target);
	}

	/**
	 * 获得指定日期，偏移指定时间
	 * @param inDate 指定时间
	 * @param deviationNum 偏移值（<0:向左偏移, >0：向右偏移）
	 * @param deviationType 偏移类型（年：Y/y, 月：M/m， 日：D/d, 时：H/h， 分：MIN/min，秒：S/s）
	 * @return
	 */
	public static Date getDayBeforeOrAfter(Date inDate, Integer changeNum, String changeType) {
		// 今天整天日期
		if (inDate == null) {
			inDate = new Date();
		}
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
		String sourceDtStr = sdf.format(inDate.getTime());
		Date sourceDay = null;
		try {
			sourceDay = sdf.parse(sourceDtStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date(sourceDay.getTime()));
		if("Y".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.YEAR, changeNum);
		} else if("M".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.MONTH, changeNum);
		} else if("D".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.DATE, changeNum);
		} else if("H".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.HOUR_OF_DAY, changeNum);
		} else if("MIN".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.MINUTE, changeNum);
		} else if("S".equals(changeType.toUpperCase())) {
			calendar.add(Calendar.SECOND, changeNum);
		}
		Date outDate = calendar.getTime();
		return outDate;
		//return sdf.format(target);
	}

	/**
	 * 获取当前秒数:从 1970年至今
	 *
	 * @return
	 */
	public static int getTimeSeconds() {
		long timeMillis = System.currentTimeMillis();
		long timeSeconds = timeMillis / 1000;
		return (int) timeSeconds;
	}

	//获取本周的开始时间
	public static Date getBeginDayOfWeek() {
		Date date = new Date();
		if (date == null) {
			return null;
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayofweek == 1) {
			dayofweek += 7;
		}
		cal.add(Calendar.DATE, 2 - dayofweek);
		return getDayStartTime(cal.getTime());
	}
	//获取本周的结束时间
	public static Date getEndDayOfWeek(){
		Calendar cal = Calendar.getInstance();
		cal.setTime(getBeginDayOfWeek());
		cal.add(Calendar.DAY_OF_WEEK, 6);
		Date weekEndSta = cal.getTime();
		return getDayEndTime(weekEndSta);
	}

	//获取本月的开始时间
	public static Date getBeginDayOfMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		return getDayStartTime(calendar.getTime());
	}
	//获取本月的结束时间
	public static Date getEndDayOfMonth(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(getNowYear(), getNowMonth() - 1, 1);
		int day = calendar.getActualMaximum(5);
		calendar.set(getNowYear(), getNowMonth() - 1, day);
		return getDayEndTime(calendar.getTime());

	}
	//获取今年是哪一年
	public static Integer getNowYear() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return Integer.valueOf(gc.get(1));
	}
	//获取本月是哪一月
	public static int getNowMonth() {
		Date date = new Date();
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		return gc.get(2) + 1;
	}

	//获取某个日期的开始时间
	public static Timestamp getDayStartTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if(null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Timestamp(calendar.getTimeInMillis());
	}
	//获取某个日期的结束时间
	public static Timestamp getDayEndTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if(null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),    calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		return new Timestamp(calendar.getTimeInMillis());
	}

	public static Date getTodayEndTime() {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.set(Calendar.HOUR_OF_DAY, 23);
		todayEnd.set(Calendar.MINUTE, 59);
		todayEnd.set(Calendar.SECOND, 59);
		todayEnd.set(Calendar.MILLISECOND, 999);
		return todayEnd.getTime();
	}

	public static Date getTodayBeginTime() {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.set(Calendar.HOUR_OF_DAY, 0);
		todayEnd.set(Calendar.MINUTE, 0);
		todayEnd.set(Calendar.SECOND, 0);
		todayEnd.set(Calendar.MILLISECOND, 0);
		return todayEnd.getTime();
	}



	public static Timestamp getbeforeTimeByMinute(Date d ,Integer minute){
		Calendar calendar = Calendar.getInstance();
		if(null != d) {
			calendar.setTime(d);
		}
		calendar.add(Calendar.MINUTE,-minute);
		return new Timestamp(calendar.getTimeInMillis());
	}

	public static String formatTimeStamp(long timeStamp){
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
		Date date = new Date(timeStamp);
		return sdf.format(date);
	}


	public static String tranToChineseTime(Integer timeLen){
		int hour = timeLen / 3600;
		int minute = timeLen % 3600 / 60;
		int second = timeLen % 3600 % 60;
		return ((hour == 0 ? "" : hour + "时") + (minute==0?"": minute+ "分") + second + "秒");
	}


    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime 当前时间（null 则默认new Date()）
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 返回代号（-1：开始时间之前，0：在区间中，1：结束时间之后）
     */
    public static int isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
    	if (nowTime== null) {
    		nowTime = new Date();
    	}
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return 0;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if(date.before(begin)) {//date.after(end)
            return -1;
        } else if (date.after(begin) && date.before(end)) {
            return 0;
        } else {
            return 1;
        }
    }

	/**
	 * date2比date1多的天数
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDays(Date date1,Date date2)
	{
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);

		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1= cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if(year1 != year2)   //同一年
		{
			int timeDistance = 0 ;
			for(int i = year1 ; i < year2 ; i ++)
			{
				if(i%4==0 && i%100!=0 || i%400==0)    //闰年
				{
					timeDistance += 366;
				}
				else    //不是闰年
				{
					timeDistance += 365;
				}
			}

			return timeDistance + (day2-day1) ;
		}
		else    //不同年
		{
		//	System.out.println("判断day2 - day1 : " + (day2-day1));
			return day2-day1;
		}
	}

	/**
	 * @Description:获取当前时间
	 * @Title: getDate
	 * @return 当前时间
	 * @author linjia
	 * @date 2020年3月5日
	 */
	public static Date getDate(){
		return new Date();
	}

	/**
	 * @Description: 设置一个新的时间，通过传入的时分秒
	 * @Title: setNewDateHour
	 * @param hour：时分秒，格式：18:18:18-->18点18分18秒
	 * @return 今天的日期加传入的时间，如果传入的时间格式错误，则返回null
	 * @author linjia
	 * @date 2020年3月2日
	 */
	public static Date setNewDateHour(String hour){
		if(StringUtils.isEmpty(hour)){
			return null;
		}
		String[] split = hour.split(":");
		if(3 != split.length){//切割出来不是时分秒则返回null

		}
		Calendar instance = Calendar.getInstance();
		instance.set(Calendar.HOUR_OF_DAY, Integer.parseInt(split[0]));
		instance.set(Calendar.MINUTE, Integer.parseInt(split[1]));
		instance.set(Calendar.SECOND, Integer.parseInt(split[2]));
		return instance.getTime();
	}

	/**
	 * @Description: 指定一个时间，增加指定小时（可以为负数，负数得到过去时间）
	 * @Title: addHour
	 * @param date：可以为null，null为当前时间
	 * @param hour：可以为负数，负数得到过去时间
	 * @return 增加N小时的时间
	 * @author linjia
	 * @date 2020年3月5日
	 */
	public static Date addHour(Date date,int hour){
		Calendar instance = Calendar.getInstance();
		if(null != date){
			instance.setTime(date);
		}
		instance.add(Calendar.HOUR_OF_DAY, hour);
		return instance.getTime();
	}
	
	/**
	 * @Description: 当前时间，增加指定秒（可以为负数，负数得到过去时间）
	 * @Title: addSecond
	 * @param second：可以为负数，负数得到过去时间
	 * @return 增加N秒的时间
	 * @author linjia
	 * @date 2020年6月23日
	 */
	public static Long addSecond(Long second){
		long currentTimeMillis = System.currentTimeMillis();
		if(null == second) {
			return currentTimeMillis;
		}
		return currentTimeMillis + (second*1000);
	}
	
	

	/**
	 * 获取定时任务执行的时间
	 * 如果是在0-8点 ,则返回今天八点
	 * 如果超过8点，则返回第二天八点
	 */
	public static Date getTaskDate(){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getDate());
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		Date zero = calendar.getTime();
		System.out.println("0点时间为 "+formatDate(zero));
		calendar.set(Calendar.HOUR_OF_DAY,8);
		Date eightHour = calendar.getTime();
		System.out.println("8点时间为 "+formatDate(eightHour));
		if(isEffectiveDate(getDate(),zero,eightHour) == 0){
			//时间区域内
			return eightHour;
		}
		return getNextDay8Hour();
	}

	//返回第二天八点时间
	public static Date getNextDay8Hour(){
		Date date = new Date();
		date.setDate(date.getDate()+1);
		date.setHours(8);
		date.setMinutes(0);
		date.setSeconds(0);
		return date;
	}

	/**
	 * 返回时间的年月
	 * @param date 时间
	 * @return 2020-10
	 */
	public static String getYYYYMM(Date date){
		String dateString = formatDate(date);
		return dateString.substring(0,7);
	}

	/**
	 * 判断两天是否相等
	 *@author liming
	 *@date 11:25 2020/6/2
	 *@param date1 时间一
     *@param date2 时间2
	 *@return true 相等
	 */
	public static boolean isSameDay(Date date1,Date date2){
		String data1Str = formatDate(date1,DATE_PATTERN_YYYY_MM_DD);
        String data2Str = formatDate(date2,DATE_PATTERN_YYYY_MM_DD);
        return data1Str.equals(data2Str);
	}
	public static void main(String[] args) throws ParseException {
		/*SimpleDateFormat format = new SimpleDateFormat("YYYY-mm-dd HH:MM:ss");
		Date bDate = format.parse("2019-10-15 00:00:00");
		Date nDate = new Date();//format.parse("2019-10-17 00:00:00");
		Date aDate = format.parse("2019-10-18 00:00:00");
		//System.out.println(isEffectiveDate(nDate, bDate, aDate));

        Calendar date15 = Calendar.getInstance();
        date15.setTime(bDate);
        Calendar date17 = Calendar.getInstance();
        date17.setTime(nDate);

        Calendar begin18 = Calendar.getInstance();
        begin18.setTime(aDate);
        System.out.println(format.format(bDate));
        System.out.println(format.format(nDate));
        System.out.println(format.format(aDate));*/

		//System.out.println(formatDate(setNewDateHour("18:59:18"),DATE_TIME_FORMAT));
		//System.out.println(formatDate(new Date(),DATE_PATTERN_CHINESE_YYYY_MM_DD));
		//System.out.println(formatDate(new Date(),DATE_PATTERN_CHINESE_MM_DD));

	//	System.out.println(formatDate(getTaskDate()));
		//System.out.println(getYYYYMM(new Date()));
		System.out.println(addSecond(0L));
		System.out.println(addSecond(120l));

	}
}
